C语言结构体中的[]问题,非高手莫进!

来源:百度知道 编辑:UC知道 时间:2024/05/04 09:13:56
#include<stdio.h>

typedef struct
{
int num;
char table[];
}tbl_t;

main()
{
tbl_t tt;

tt.num=1;
tt.table[0]=2;
printf("tt: \t%p,%d\n",&tt,sizeof(tt));
printf("tt.num: \t%p,%d\n",&tt.num,tt.num);
printf("tt.table:\t%p,%d\n",&tt.table[0],tt.table[0]);
}

该程序运行没有错误,输出是:
0012FF7C,4
0012FF7C,4
0012FF80,1

为什么,table作为结构体成员,没有占用任何空间呢?
修改成这样:
#include<stdio.h>

typedef struct
{
int num;
char table[];
}tbl_t;

main()
{
int begin=0;
tbl_t tt={0};
int other=0;

tt.num=1;
tt.table[0]=2;
printf("tt: \t%p,%d\n",&tt,sizeof(tt));
printf("tt.num: \t%p,%d\n",&tt.num,sizeof(tt.num));
printf("tt.table:\t%p,%d\n",&tt.table[0],tt.table

编译对那个 char table[]; 这种定义会默认解释成 char table[0];
零长数组, 这个特性多数是编译器的扩展, 零长数组是不占用空间的,你它进行 sizeof() 返回是零, 它只是在语法上提供一个符号, 访问它相关于访问 tt.num 后续的内存, 就像你第二个例子, 由于局部变量是在栈上分配的, 所以 tt.table[0] 正好落在 begin 上第一个字节上(即低字节), 所以 tt.table[0] = 2 相当于:
((char *)&begin)[0] = 2;

没有给table分配空间,自然是地址不定了阿

在C语言中,只有定义了变量系统才给分配空间,
而char table[];这句话相当于char table[0];没有申请到内存空间,只给了个起始地址,应为根本就没有定义变量,只有char table[1];或者别的数字,才表示定义了char型变量table[0],只有定义了变量系统才给分配空间所以申请到的内存为0, 而且写成这样char table[1];表示从起始地址char table[]开始有了偏移量,并且因为是结构体,分配单位是4个字节,也就是说写成这样的char table[1];表示分配到4个字节大小的空间,直到char table[5];是才分配下一个单位的空间,即为8个字节的空间。

零长度数组:

它们作为结构体的最后一个元素十分有用,如果结构体确实是变长对象的首部:

struct line {
int length;
char contents[0];
};

struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;

在ISO C89中,你需要给目录分配长度1,意味着要浪费空间或者使malloc的参数变得复杂。

在ISO C99中,你可以使用灵活的数组元素,只是在语法和主义上有微小的差异。